
namespace ShoppingCart.WebSite.Admin
{
    using System;
    using System.Configuration;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Business.Entity.Collections;
    using Business.Entity.Enums;
    using Business.Logic;
    using Code;
    using DTO = Business.Entity;

    public partial class Pedido : BasePage
    {
        private static DetallePedidoCollection _detalle;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack) return;
            _detalle = new DetallePedidoCollection();
            CargarClientes();
            CargarEstados();
            CargarDepartamentos();
            CargarDocumentos();
            CargarBancos();
            CargarAccion();
            EnlazarDetalle();
        }

        protected void DdlDepartamentoSeletedIndexChange(object sender, EventArgs e)
        {
            var idDepartamento = Convert.ToInt32(ddlDepartamento.SelectedValue);
            CargarProvincias(idDepartamento);
        }

        protected void DdlBancoSelectedIndexChange(object sender, EventArgs e)
        {
            var idBanco = Convert.ToInt32(ddlBanco.SelectedValue);
            CargarCuentas(idBanco);
        }

        protected void DdlCuentaSeletedIndexChange(object sender, EventArgs e)
        {
            var idCuenta = Convert.ToInt32(ddlCuenta.SelectedValue);
            var cuenta = CuentaManager.Instancia.Obtener(idCuenta);
            litMoneda.Text = cuenta.Moneda;
        }

        protected void DdlProvinciaSelectedIndexChanged(object sender, EventArgs e)
        {
            var idProvincia = Convert.ToInt32(ddlProvincia.SelectedValue);
            CargarDistritos(idProvincia);
        }

        protected void DdlDistritoSelectedIndexChanged(object sender, EventArgs e)
        {
            var idDistrito = Convert.ToInt32(ddlDistrito.SelectedValue);
            CalcularMontos();
        }

        protected void ChkEnviarCheckedChanged(object sender, EventArgs e)
        {
            panEnvio.Visible = chkEnviar.Checked;
        }

        protected void LvDetalleItemCommand(object sender, ListViewCommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "Insert":
                    AgregarDetalle(e.Item);
                    break;
                case "Update":
                    ModificarDetalle(Convert.ToInt32(e.CommandArgument), e.Item);
                    break;
                case "Delete":
                    EliminarDetalle(Convert.ToInt32(e.CommandArgument));
                    break;
            }
        }

        protected void LvDetalleItemCanceling(object sender, ListViewCancelEventArgs e)
        {
            switch (e.CancelMode)
            {
                case ListViewCancelMode.CancelingEdit:
                case ListViewCancelMode.CancelingInsert:
                    lvDetalle.EditIndex = -1;
                    break;
                default:
                    break;
            }
            EnlazarDetalle();
        }

        protected void LvDetalleItemEditing(object sender, ListViewEditEventArgs e)
        {
            lvDetalle.EditIndex = e.NewEditIndex;
            BindControl<DTO.DetallePedido>.BindListView(lvDetalle, _detalle);
        }

        protected void LvDetalleItemDeleting(object sender, ListViewDeleteEventArgs e)
        {
            // Sin codigo evitando la actualización por defecto
        }

        protected void LvDetalleItemInserting(object sender, ListViewInsertEventArgs e)
        {
            // Sin codigo evitando la actualización por defecto
        }

        protected void LvDetalleItemUpdating(object sender, ListViewUpdateEventArgs e)
        {
            // Sin codigo evitando la actualización por defecto
        }

        protected void DdlProductoSelectedIndexChange(object sender, EventArgs e)
        {
            var combo = (DropDownList)sender;
            var idProducto = Convert.ToInt32(combo.SelectedValue);
            var idDepartamento = Convert.ToInt32(ddlDepartamento.SelectedValue);
            var producto = ProductoDepartamentoManager.Instancia.Obtener(idProducto, idDepartamento);
            var textbox = (TextBox)combo.Parent.FindControl("txtPrecio");
            textbox.Text = producto.Precio.ToString();
        }

        protected void BtnGuardarClick(object sender, EventArgs e)
        {
            GuardarAccion();
        }

        private void CargarAccion()
        {
            var accion = Request.QueryString.Get("Accion");
            if (string.IsNullOrEmpty(accion))
                Response.Redirect("Pedido.aspx", true);
            switch (accion)
            {
                case "I":
                    litAccion.Text = @"INGRESAR";
                    break;
                case "M":
                    var idPedido = Convert.ToInt32(Request.QueryString.Get("idPedido"));
                    CargarPedido(idPedido);
                    litAccion.Text = @"MODIFICAR";
                    break;
            }
        }

        private void CargarClientes()
        {
            var clientes = ClienteManager.Instancia.Listar();
            BindControl<DTO.Cliente>.BindDropDownList(ddlCliente, clientes);
        }

        private void CargarEstados()
        {
            ddlEstado.DataSource = Enum.GetNames(typeof(Estado));
            ddlEstado.DataBind();

            ddlEstadoEnvio.DataSource = Enum.GetNames(typeof(Estado));
            ddlEstadoEnvio.DataBind();
        }

        private void CargarDepartamentos()
        {
            var departamentos = DepartamentoManager.Instancia.Listar(false);
            BindControl<DTO.Departamento>.BindDropDownList(ddlDepartamento, departamentos);
            if (departamentos.Count == 0) return;
            CargarProvincias(departamentos.First().IdDepartamento);
        }

        private void CargarProvincias(int idDepartamento)
        {
            var provincias = ProvinciaManager.Instancia.ListarPorIdDepartamento(idDepartamento, true);
            BindControl<DTO.Provincia>.BindDropDownList(ddlProvincia, provincias);
            if (provincias.Count == 0) return;
            CargarDistritos(provincias.First().IdProvincia);
        }

        private void CargarDistritos(int idProvincia)
        {
            var distritos = DistritoManager.Instancia.ListarPorIdProvincia(idProvincia, true);
            BindControl<DTO.Distrito>.BindDropDownList(ddlDistrito, distritos);
            CalcularMontos();
        }

        private void CargarDocumentos()
        {
            ddlDocumento.DataSource = Enum.GetNames(typeof(Documento));
            ddlDocumento.DataBind();
        }

        private void CargarBancos()
        {
            var bancos = BancoManager.Instancia.Listar();
            BindControl<DTO.Banco>.BindDropDownList(ddlBanco, bancos);
            if (bancos.Count == 0) return;
            CargarCuentas(bancos.First().IdBanco);
        }

        private void CargarCuentas(int idBanco)
        {
            var cuentas = CuentaManager.Instancia.ListarPorIdBanco(idBanco);
            ddlCuenta.DataTextField = "Numero";
            ddlCuenta.DataValueField = "IdCuenta";
            ddlCuenta.DataSource = cuentas;
            ddlCuenta.DataBind();
            if (cuentas.Count == 0) return;
            litMoneda.Text = cuentas.First().Moneda;
        }

        private void AgregarDetalle(ListViewItem item)
        {
            var idProducto = Convert.ToInt32(((DropDownList)item.FindControl("ddlProducto")).SelectedValue);
            var detalle = _detalle.Where(p => p.IdProducto == idProducto).SingleOrDefault();
            if (detalle == null)
            {
                _detalle.Add(new DTO.DetallePedido
                {
                    IdProducto = idProducto,
                    Cantidad = Convert.ToInt32(((TextBox)item.FindControl("txtCantidad")).Text),
                    Precio = Convert.ToDecimal(((TextBox)item.FindControl("txtPrecio")).Text),
                    Descuento = Convert.ToDecimal(((TextBox)item.FindControl("txtDescuento")).Text)
                });
            }
            else
            {
                detalle.Cantidad = Convert.ToInt32(((TextBox)item.FindControl("txtCantidad")).Text);
                detalle.Precio = Convert.ToDecimal(((TextBox)item.FindControl("txtPrecio")).Text);
                detalle.Descuento = Convert.ToDecimal(((TextBox)item.FindControl("txtDescuento")).Text);
            }
            lvDetalle.EditIndex = -1;
            EnlazarDetalle();
        }

        private void ModificarDetalle(int idProducto, ListViewItem item)
        {
            var detalle = _detalle.Where(p => p.IdProducto == idProducto).SingleOrDefault();
            detalle.Cantidad = Convert.ToInt32(((TextBox)item.FindControl("txtCantidad")).Text);
            detalle.Precio = Convert.ToDecimal(((TextBox)item.FindControl("txtPrecio")).Text);
            detalle.Descuento = Convert.ToDecimal(((TextBox)item.FindControl("txtDescuento")).Text);
            lvDetalle.EditIndex = -1;
            EnlazarDetalle();
        }

        private void EliminarDetalle(int idProducto)
        {
            _detalle.RemoveAll(p => p.IdProducto == idProducto);
            EnlazarDetalle();
        }

        private void EnlazarDetalle()
        {
            CalcularMontos();
            BindControl<DTO.DetallePedido>.BindListView(lvDetalle, _detalle);
        }

        private void CargarPedido(int idPedido)
        {
            var pedido = PedidoManager.Instancia.Obtener(idPedido);
            ddlCliente.SelectedValue = pedido.Cliente.IdCliente.ToString();
            ddlDepartamento.SelectedValue = pedido.Departamento.IdDepartamento.ToString();
            txtFecha.Text = pedido.Fecha.ToString("dd/MM/yyyy");
            ddlDocumento.SelectedValue = pedido.NombreDocumento;
            txtNroOperacion.Text = pedido.NroOperacion;
            txtFechaOperacion.Text = pedido.FechaOperacion.ToString("dd/MM/yyyy");
            ddlBanco.SelectedValue = pedido.Banco.IdBanco.ToString();
            CargarCuentas(pedido.Banco.IdBanco);
            ddlCuenta.SelectedValue = pedido.Cuenta.IdCuenta.ToString();
            ddlEstado.Text = pedido.NombreEstado;
            litAutorizador.Text = pedido.Autorizador;
            txtDescripcion.Text = pedido.Descripcion;
            _detalle = pedido.Detalle;

            if (pedido.Envio != null)
            {
                chkEnviar.Checked = true;
                panEnvio.Visible = true;
                ddlProvincia.SelectedValue = pedido.Envio.Distrito.Provincia.IdProvincia.ToString();
                CargarDistritos(pedido.Envio.Distrito.Provincia.IdProvincia);
                ddlDistrito.SelectedValue = pedido.Envio.Distrito.IdDistrito.ToString();
                txtDireccion.Text = pedido.Envio.Direccion;
                txtReferencia.Text = pedido.Envio.Comentario;
                txtFechaEnvio.Text = pedido.Envio.FechaEnvio.HasValue ? pedido.Envio.FechaEnvio.Value.ToString("dd/MM/yyyy") : string.Empty;
                ddlEstadoEnvio.SelectedValue = pedido.Envio.NombreEstado;
            }
            else
            {
                chkEnviar.Checked = false;
                panEnvio.Visible = false;
            }
        }

        private void CalcularMontos()
        {
            if (_detalle.Count == 0) return;
            var monto = _detalle.Sum(p => p.Cantidad * p.Precio);
            litTotal.Text = monto.ToString("C");

            if (ddlDistrito.SelectedValue == null) return;
            var idDistrito = Convert.ToInt32(ddlDistrito.SelectedValue);
            var distrito = DistritoManager.Instancia.Obtener(idDistrito);

            var cantidad = _detalle.Sum(p => p.Cantidad);
            var envio = distrito.Flete * cantidad; 
            litEnvio.Text = envio.ToString("C");
            monto += envio;

            var path = Server.MapPath(ConfigurationManager.AppSettings["Parametros"]);
            var parametros = ParametroManager.Instancia.Listar(path);
            if (parametros.Count == 3)
            {
                var parametroA = parametros[0];
                if (cantidad > parametroA.Cantidad)
                {
                    var parametroB = parametros[1];
                    if (cantidad > parametroB.Cantidad)
                    {
                        var parametroC = parametros[2];
                        if (cantidad > parametroC.Cantidad)
                        {
                            monto = monto - parametroC.Descuento;
                            litDescuento.Text = parametroC.Descuento.ToString("C");
                            litDescuentoEnvio.Text = "Por la compra mayor a " + parametroC.Cantidad + " productos su descuento es " + parametroC.Descuento.ToString("C");
                        }
                        else
                        {
                            monto = monto - parametroB.Descuento;
                            litDescuento.Text = parametroB.Descuento.ToString("C");
                            litDescuentoEnvio.Text = "Por la compra mayor a " + parametroB.Cantidad + " productos su descuento es " + parametroB.Descuento.ToString("C");
                        }
                    }
                    else
                    {
                        monto = monto - parametroA.Descuento;
                        litDescuento.Text = parametroA.Descuento.ToString("C");
                        litDescuentoEnvio.Text = "Por la compra mayor a " + parametroA.Cantidad + " productos su descuento es " + parametroA.Descuento.ToString("C");
                    }
                }
                else litDescuentoEnvio.Text = "S/.0.00, la cantidad comprada no asciende a un descuento.";
            }
            else litDescuentoEnvio.Text = "S/.0.00, la cantidad comprada no asciende a un descuento.";

            litTotalNeto.Text = monto.ToString("C");
        }

        private void GuardarAccion()
        {
            var accion = Request.QueryString.Get("Accion");
            switch (accion)
            {
                case "I":
                    InsertarPedido();
                    break;
                case "M":
                    ModificarPedido();
                    break;
            }
        }

        private void InsertarPedido()
        {
            var pedido = new DTO.Pedido
            {
                Cliente = new DTO.Cliente { IdCliente = Convert.ToInt32(ddlCliente.SelectedValue) },
                Departamento = new DTO.Departamento { IdDepartamento = Convert.ToInt32(ddlDepartamento.SelectedValue) },
                Fecha = GetCurrentDatetime(txtFecha.Text),
                Documento = (byte)Enum.Parse(typeof(Documento), ddlDocumento.SelectedValue),
                Cuenta = new DTO.Cuenta { IdCuenta = Convert.ToInt32(ddlCuenta.SelectedValue) },
                NroOperacion = txtNroOperacion.Text,
                FechaOperacion = GetCurrentDatetime(txtFechaOperacion.Text),
                Descripcion = txtDescripcion.Text,
                Estado = (byte)Enum.Parse(typeof(Estado), ddlEstado.SelectedValue),
                Autorizador = User.Identity.Name,
                Detalle = _detalle,
                Envio = null
            };
            if (chkEnviar.Checked)
            {
                pedido.Envio = new DTO.Envio
                {
                    Distrito = new DTO.Distrito { IdDistrito = Convert.ToInt32(ddlDistrito.SelectedValue) },
                    Direccion = txtDireccion.Text,
                    Comentario = txtReferencia.Text,
                    Estado = (byte)Enum.Parse(typeof(Estado), ddlEstadoEnvio.SelectedValue),
                    FechaEnvio = string.IsNullOrEmpty(txtFechaEnvio.Text) ? (DateTime?)null : GetCurrentDatetime(txtFechaEnvio.Text),
                    Costo = CurrencyToDecimal(litEnvio.Text)
                };
            }
            try
            {
                PedidoManager.Instancia.Agregar(pedido);
                ClientScript.RegisterStartupScript(GetType(), "mostrar1", "alert('Registro grabado satisfactoriamente');window.location = 'Pedidos.aspx';", true);
            }
            catch
            {
                ClientScript.RegisterStartupScript(GetType(), "mostrar1", "alert('No se pudo Agregar Pedido, por favor intente de nuevo o más tarde.');", true);
            }
        }

        private void ModificarPedido()
        {
            var idPedido = Convert.ToInt32(Request.QueryString.Get("idPedido"));
            var pedido = PedidoManager.Instancia.Obtener(idPedido);

            pedido.Cliente.IdCliente = Convert.ToInt32(ddlCliente.SelectedValue);
            pedido.Departamento.IdDepartamento = Convert.ToInt32(ddlDepartamento.SelectedValue);
            pedido.Fecha = GetCurrentDatetime(txtFecha.Text);
            pedido.Documento = (byte)Enum.Parse(typeof(Documento), ddlDocumento.SelectedValue);
            pedido.Cuenta.IdCuenta = Convert.ToInt32(ddlCuenta.SelectedValue);
            pedido.NroOperacion = txtNroOperacion.Text;
            pedido.FechaOperacion = GetCurrentDatetime(txtFechaOperacion.Text);
            pedido.Descripcion = txtDescripcion.Text;
            pedido.Estado = (byte)Enum.Parse(typeof(Estado), ddlEstado.SelectedValue);
            pedido.Autorizador = User.Identity.Name;
            pedido.Detalle = _detalle;

            if (chkEnviar.Checked)
            {
                if (pedido.Envio == null)
                {
                    pedido.Envio = new DTO.Envio
                    {
                        Distrito = new DTO.Distrito { IdDistrito = Convert.ToInt32(ddlDistrito.SelectedValue) },
                        Direccion = txtDireccion.Text,
                        Comentario = txtReferencia.Text,
                        Estado = (byte)Enum.Parse(typeof(Estado), ddlEstadoEnvio.SelectedValue),
                        FechaEnvio = string.IsNullOrEmpty(txtFechaEnvio.Text) ? (DateTime?)null : GetCurrentDatetime(txtFechaEnvio.Text),
                        Costo = CurrencyToDecimal(litEnvio.Text)
                    };
                }
                else
                {
                    pedido.Envio.Distrito.IdDistrito = Convert.ToInt32(ddlDistrito.SelectedValue);
                    pedido.Envio.Direccion = txtDireccion.Text;
                    pedido.Envio.Comentario = txtReferencia.Text;
                    pedido.Envio.Estado = (byte)Enum.Parse(typeof(Estado), ddlEstadoEnvio.SelectedValue);
                    pedido.Envio.FechaEnvio = string.IsNullOrEmpty(txtFechaEnvio.Text) ? (DateTime?)null : GetCurrentDatetime(txtFechaEnvio.Text);
                    pedido.Envio.Costo = CurrencyToDecimal(litEnvio.Text);
                }
            }
            else
            {
                pedido.Envio = null;
            }

            try
            {
                PedidoManager.Instancia.Modificar(pedido);
                ClientScript.RegisterStartupScript(GetType(), "mostrar2", "alert('Registro grabado satisfactoriamente');window.location = 'Pedidos.aspx';", true);
            }
            catch
            {
                ClientScript.RegisterStartupScript(GetType(), "mostrar1", "alert('No se pudo Modificar Pedido, por favor intente de nuevo o más tarde.');", true);
            }
        }
    }
}
